package net.loogn.stardust.server;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Set;

/**
 * Created by Administrator on 2017/4/7.
 */
class ActionManager {
    static HashMap<String, ActionWrapper> actionDict;

    static void loadActions(Set<Class> serviceClasses) throws ClassNotFoundException, IllegalAccessException, InstantiationException {

        actionDict = new HashMap<String, ActionWrapper>();
        for (Class cls : serviceClasses) {
            String bigPath;
            StardustName clsAnnotation = (StardustName) cls.getAnnotation(StardustName.class);
            if (clsAnnotation != null) {
                bigPath = clsAnnotation.value().toLowerCase();
            } else {
                bigPath = cls.getSimpleName().toLowerCase();
                if (bigPath.endsWith("service")) {
                    bigPath = bigPath.substring(0, bigPath.length() - 7);
                }
            }
            Object obj = cls.newInstance();
            for (Method method : cls.getMethods()) {
                if (method.getDeclaringClass().equals(cls) && !method.getReturnType().getName().equals("void")) {
                    Class[] psTypes = method.getParameterTypes();
                    if (psTypes == null || psTypes.length == 0 || (psTypes.length == 1 && psTypes[0].equals(String.class))) {
                        String smallPath;
                        StardustName methodAnnotation = method.getAnnotation(StardustName.class);
                        if (methodAnnotation != null) {
                            smallPath = methodAnnotation.value().toLowerCase();
                        } else {
                            smallPath = method.getName().toLowerCase();
                        }
                        String path = "/" + bigPath + "/" + smallPath;
                        //System.out.println("Register:" + path);
                        actionDict.put(path, new ActionWrapper(obj, method, psTypes.length));
                    }
                }
            }
        }
    }

    static ActionWrapper getActionWrapper(String path) {
        return actionDict.get(path);
    }

    static class ActionWrapper {
        private Method _method;
        private Object _obj;
        private int _psCount;

        public ActionWrapper(Object obj, Method method, int psCount) {
            _obj = obj;
            _method = method;
            _psCount = psCount;
        }

        public Object invoke(String json) throws InvocationTargetException, IllegalAccessException {
            System.out.println("invoke json : " + json);
            if (_psCount == 0) {
                return _method.invoke(_obj);
            } else {
                return _method.invoke(_obj, json);
            }
        }
    }
}

